home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*
- * Yossi Friedman, July 1988
- */
-
-
- #ifdef MAIN
- # define extern /* nothing */
- # define INIT(val) = val
- #else /* MAIN */
- # define INIT(val) /* nothing */
- #endif /* MAIN */
-
-
-
- /*
- * set the right flags depending on the current graphics board
- */
- #ifdef CLOVER1
- # undef HAS_CZCLEAR
- # undef HAS_BLENDING
- # undef MP
- #endif /* CLOVER1 */
-
- #ifdef ECLIPSE
- # define HAS_CZCLEAR
- # undef HAS_BLENDING
- # undef MP
- #endif /* ECLIPSE */
-
- #ifdef CLOVER1G
- # define HAS_CZCLEAR
- # define HAS_BLENDING
- # undef MP
- #endif /* CLOVER1G */
-
- #ifdef CLOVER2
- # define HAS_CZCLEAR
- # define HAS_BLENDING
- # define MP
- #endif /* CLOVER2 */
-
- /*
- * Multiprocessor stuff
- */
- #ifdef MP
-
- extern int nproc; /* number of CPUs */
- extern void slave(void *);
-
- /* functions that slaves can perform: */
- # define SLAVE_IDLE 0
- # define SLAVE_DIE 1
- # define DO_CLEAR 2
- # define DO_ACCEL 3
- # define DO_BOUNDS 4
- # define DO_VEL_DAMP_POS 5
- # define DO_ROTATE_MODEL 6
- # define DO_ROTATE_PHYSICS 7
- # define DRAW_FLAT_SURFS_1 8
- # define DRAW_SMOOTH_SURFS_1 9
- # define DRAW_SMOOTH_SURFS_2 10
- # define DRAW_SMOOTH_SURFS_3 11
-
- # define SLAVE_FUNC(f) \
- do { \
- int i; \
- \
- for (i = 0; i < nproc; i++) \
- slave_func[i] = f; \
- } while (0)
-
- # define WAIT_FOR_SLAVE() \
- do { \
- int waiting; \
- int i; \
- \
- for (waiting = 1; waiting;) { \
- waiting = 0; \
- for (i = 1; i < nproc; i++) \
- if (slave_func[i] != SLAVE_IDLE) { \
- waiting = 1; \
- break; \
- } \
- } \
- } while (0);
-
- # define MP_ARRAY [MAX_NPROC]
- # define CPU_PARAM , cpu
- # define MASTER_PARAM , 0
- # define CPU_PARAM_TYPE int cpu
- # define CPU [cpu]
- # define MASTER [0]
- # define TOTAL [nproc-1]
-
-
- extern volatile int slave_func MP_ARRAY;
- extern int slave_pid MP_ARRAY;
-
- /*
- * debugging -- DO NOT start the slaves in the main program. Instead,
- * redefine WAIT_FOR_SLAVE as:
- *
- * # define WAIT_FOR_SLAVE() \
- * do { \
- * int i; \
- * for (i = 1; i < nproc; i++) \
- * slave(); \
- * \
- * slave_func[0] = 1; \
- * for (i = 1; i < nproc; i++) \
- * slave_func[0] &&= (slave_func[i] == SLAVE_IDLE); \
- * if (slave_func[0] == 0) \
- * fprintf(stderr, "Slave(s) don't signal!\007\n"); \
- * } while (0)
- *
- * Also, remove the infinite loop from the slave routine.
- */
-
- #else /* MP */
-
- # define SLAVE_FUNC(f) do /* nothing */ ; while (0)
- # define MP_ARRAY /* nothing */
- # define SLAVE_IDLE /* nothing */
- # define WAIT_FOR_SLAVE() do /* nothing */ ; while (0)
- # define CPU_PARAM /* nothing */
- # define MASTER_PARAM /* nothing */
- # define CPU_PARAM_TYPE /* nothing */
- # define CPU /* nothing */
- # define MASTER /* nothing */
- # define TOTAL /* nothing */
-
- #endif /* MP */
-
-
-
-
- /*
- * indices into a coordinate vector
- */
- #define X 0
- #define Y 1
- #define Z 2
- #define W 3
-
-
- /*
- * useful vector macros. they are enclosed in this ridiculous null loop in
- * order the make each a pseudo-statement.
- *
- * NOTE: the operands are nor parenthesized, so the macros should
- * be invoked with care (priority of operators).
- */
- #define vec_op(v, v1, op, v2) \
- /* v = v1 op v2 */ \
- do { \
- v[X] = v1[X] op v2[X]; \
- v[Y] = v1[Y] op v2[Y]; \
- v[Z] = v1[Z] op v2[Z]; \
- } while (0)
-
- #define cross(v, v1, v2) \
- /* v = v1 x v2 */ \
- do { \
- v[X] = v1[Y]*v2[Z] - v1[Z]*v2[Y] ; \
- v[Y] = -(v1[X]*v2[Z] - v1[Z]*v2[X]); \
- v[Z] = v1[X]*v2[Y] - v1[Y]*v2[X] ; \
- } while (0)
-
- #define dot(v1, v2) (v1[X]*v2[X] + v1[Y]*v2[Y] + v1[Z]*v2[Z])
-
- #define apply(b, a, M) \
- /* b = a M */ \
- do { \
- b[X] = a[X]*M[X][X] + a[Y]*M[Y][X] + a[Z]*M[Z][X] + M[W][X]; \
- b[Y] = a[X]*M[X][Y] + a[Y]*M[Y][Y] + a[Z]*M[Z][Y] + M[W][Y]; \
- b[Z] = a[X]*M[X][Z] + a[Y]*M[Y][Z] + a[Z]*M[Z][Z] + M[W][Z]; \
- } while (0)
-
- #define normalize(v) \
- /* v = v / |v| */ \
- do { \
- \
- float leni = 1. / sqrt(v[X]*v[X] + v[Y]*v[Y] + v[Z]*v[Z]); \
- \
- v[X] *= leni; \
- v[Y] *= leni; \
- v[Z] *= leni; \
- } while (0)
-
-
-
-
-
-
- /*
- * models catalog file
- */
- extern char *model_catalog INIT(DEFAULT_MODEL_CATALOG);
-
-
-
- #ifdef CONFIG_FILE
-
- /*
- * configuration file
- */
- extern char *model_config INIT(DEFAULT_MODEL_CONFIG);
-
- #endif /* CONFIG_FILE */
-
-
-
-
- /*
- * the list of models
- */
- extern char *model_names[MAX_MODELS], **end_model_names;
- extern int model_index; /* index of current model in the name list */
-
-
-
- /*
- * the physical and geometric elements of the system
- */
- typedef struct {
- /* physics stuff */
- float acc MP_ARRAY [3];
- float vel[3];
-
- /* shared stuff between physics and draw */
- float pos[3];
-
- /* draw stuff */
- float norm MP_ARRAY [3];
- } Atom;
-
- typedef struct {
- float r0;
- float k;
- Atom *from;
- Atom *to;
- } Spring;
-
- typedef struct {
- int n;
- Atom **vert;
- float *norm; /* array of normals, size 4*n. 4 rather than 3 so it
- would be fast to go from one normal to the next */
- } Surf;
-
- extern Atom model_atoms[MAX_ATOMS], *end_model_atoms MP_ARRAY;
- extern Spring model_springs[MAX_SPRING], *end_model_springs MP_ARRAY;
- extern Surf model_surfs[MAX_SURF], *end_model_surfs MP_ARRAY;
-
- extern float max_k; /* current maximal model spring constant */
-
-
-
- #define MODEL_MATERIAL_INDEX 1
- extern float model_material[MAX_LIGHTING_SIZE];
- extern int model_material_size;
-
- extern float default_model_material[MAX_LIGHTING_SIZE]
- INIT({ DEFAULT_MODEL_MATERIAL });
- extern int default_model_material_size
- INIT(DEFAULT_MODEL_MATERIAL_SIZE);
-
-
-
-
- /*
- * room walls structure
- */
- extern struct wall {
- /* draw stuff */
- float real_v[4][3]; /* real vertices of the wall */
- float real_norm[3];
- float surf_v[4][3]; /* vertices of the wall surface */
- float surf_e[4][3]; /* edges of the wall surface */
- float surf_norm[5][3]; /* normals for dented walls */
- float shadow[4][4]; /* shadow transformation matrix */
-
- int axis; /* which axis does the wall lie on */
- float sign; /* on which side of that axis? +/- 1. */
-
- /* shared stuff between physics and draw -- penetrations into walls */
- int penetrated;
- float depth;
- Atom *atom;
- } wall[6];
-
- #define WALL_TOP 0
- #define WALL_BOTTOM 1
- #define WALL_RIGHT 2
- #define WALL_LEFT 3
- #define WALL_FRONT 4
- #define WALL_BACK 5
-
-
-
- /*
- * draw functions
- */
- extern void draw_smooth_surfs(),
- draw_flat_surfs(),
- draw_springs(),
- (*draw_model)();
-
- extern void draw_lighted_wall(int),
- draw_pinball_wall(int),
- draw_plain_wall(int),
- (*draw_wall)(int) INIT(DRAW_WALL_DEFAULT);
-
-
-
- /*
- * display state vars
- */
-
- /* display mode -- color map or RGB */
- #define RGB 1
- #define COLOR_MAP 0
- extern int mode INIT(DEFAULT_MODE);
-
- /* should we draw shadows in lighted wall mode? */
- extern int shadows_too INIT(SHADOWS_TOO_DEFAULT);
-
- /* should the springs be drawn as well as the surfaces? */
- extern int springs_too INIT(SPRINGS_TOO_DEFAULT);
-
- /* should we draw a translucent model? */
- extern int alpha_blended INIT(ALPHA_BLENDED_DEFAULT);
-
-
-
-
-
-
-
- /*
- * sliders stuff -- common to physics and play:initialize_sliders.
- * Physics sets the title, low, hi, dflt, and fun, as well as end_sliders.
- * In initialize_sliders, the sid gets set.
- */
- struct slider {
- char *title;
- float lo, hi, dflt;
- void (*fun)(float);
-
- int sid;
- };
- extern struct slider sliders[100], *end_sliders;
-
-
-
-
-
-
- /*
- * It transpires that because of the user interface, my transformation
- * mechanism has to be somewhat different from the one supported by GL.
- * I have to separate M (modeling transformations), V (viewing
- * trans.) and P (projection trans.). P has to be separated from the
- * others because of the lighting model. V and M have to be separated
- * because of the rotation of the COORDINATE SYSTEM (rather than the
- * objects themselves) -- this forces post-multiplication of M.
- * Hence, I use `mmode(MVIEWING)' to keep P separated from the others,
- * I keep a constant V at the top of the stack, and I keep M and M-inverse
- * soft in my program.
- *
- * The routine `rotate_graphics' in file draw.c actually changes M
- * and M-inverse. The routines `rotate_model' (models.c) and
- * `rotate_physics' (physics.c) use those matrices. The reason why they
- * need to use them is because rotations happen around a fixed axis in
- * the viewing coordinate system, and the coordinates of the model and
- * gravity vector are in the modeling coordinate system, which is attached
- * to the room -- so in order to rotate around a viewing axis, the model
- * and gravity coordinates have to be transformed into viewing coordinates,
- * rotated, and returned to modeling coordinates.
- */
-
- #define IDENT_MATRIX \
- { \
- { 1., 0., 0., 0. }, \
- { 0., 1., 0., 0. }, \
- { 0., 0., 1., 0. }, \
- { 0., 0., 0., 1. } \
- }
-
- extern Matrix ident_matrix INIT(IDENT_MATRIX);
- extern Matrix M INIT(IDENT_MATRIX);
- extern Matrix M_inv INIT(IDENT_MATRIX);
- extern Matrix R; /* general purpose */
-
- #undef IDENT_MATRIX
-
-
-
- #ifdef MAIN
- # undef extern
- #endif /* MAIN */
-
- #undef INIT
-
- extern void set_default_k(float);
- extern void set_k(float);
-
-